package ad
{	
	/**
	 * List
	 * @version ActionScript 3.0
	 * @author Adrian C. Miranda
	 * @mail ad@adrianmiranda.com.br
	 */
	public final class List
	{
		protected var list:Array;
		protected var index:int;
		
		public function List(items:Array = null)
		{
			list = items || new Array();
		}
		
		public function first():Object
		{
			return this.list[this.index = 0];
		}
		
		public function last():Object 
		{
			return this.list[this.index = this.list.length ? this.list.length - 1 : this.list.length];
		}
		
		public function previous():Object 
		{
			return this.list[this.hasPrevious ? --this.index : this.index];
		}
		
		public function next():Object 
		{
			return this.list[this.hasNext ? ++this.index : this.index];
		}
		
		public function contains(item:Object):Boolean
		{
			return (this.list.indexOf(item) != -1);
		}
		
		public function addItem(item:Object):void 
		{
			this.list.push(item);
		}
		
		public function addItemAt(item:Object, index:int):void 
		{
			index = Math.max(0, index);
			index = Math.min(this.list.length, index);
			this.list.splice(index, 0, item);
		}
		
		public function removeItem(item:Object):void 
		{
			var index:int = this.list.indexOf(item);
			this.removeItemAt(index);
		}
		
		public function removeItemAt(index:int):void
		{
			if (index < 0 || index >= this.list.length)
			{
				trace(index, 'is a invalid index.'); return;
			}
			this.list.splice(index, 1);
		}
		
		public function removeAll():void
		{
			this.list.length = 0;
		}
		
		public function reverse():Array
		{
			return this.list.reverse();
		}
		
		public function isEqual(list:List):Boolean
		{
			if (this.list.length != list.length)
			{
				return false;
			}
			for (var id:int = 0; id < this.list.length; id++)
			{
				if (this.list[id] !== list[id])
				{
					return false;
				}
			}
			return true;
		}
		
		public function get hasNext():Boolean { return (this.index < this.list.length - 1); }
		public function get hasPrevious():Boolean  { return (this.index > 0); }
		public function get currentItem():Object { return this.list[this.index]; }
		public function get currentIndex():int { return this.index; }
		public function get length():int { return this.list.length; }
		public function set items(items:Array):void 
		{
			this.list = items;
		}
		
	}

}